package com.spiro.test.net.tcp.ssl.bidirectional;

import com.spiro.test.net.common.Configuration;

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.util.Scanner;

/**
 * Created by tz0643 on 2016/6/17.

 */
public class SSLTcpClient {

    private SSLSocket socket = null;
    private BufferedReader reader = null;
    private PrintWriter writer = null;

    public void start(int port,
                      String keyStoreFilename, String keyStorePwd,
                      String trustKeyStoreFilename, String trustKeyStorePwd) throws Exception {

        KeyStore clientKeyStore = KeyStore.getInstance("JKS");
        clientKeyStore.load(new FileInputStream(keyStoreFilename),
                keyStorePwd.toCharArray());

        KeyStore clientTrustKeyStore = KeyStore.getInstance("JKS");
        clientTrustKeyStore.load(new FileInputStream(trustKeyStoreFilename),
                trustKeyStorePwd.toCharArray());

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(clientKeyStore, keyStorePwd.toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(clientTrustKeyStore);

        SSLContext sslContext = SSLContext.getInstance("TLSv1");
        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        try {
            SSLSocketFactory factory = sslContext.getSocketFactory();
            socket = (SSLSocket) factory.createSocket("localhost", port);
            System.out.println("Connected, port -> " + port);
        } catch (IOException e) {
            throw e;
        }

        try {
            reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
            writer = new PrintWriter(this.socket.getOutputStream());

            Scanner scanner = new Scanner(System.in);

            while (true) {
                System.out.println("input -> ");
                String input = scanner.next();
                writer.println(input);
                writer.flush();

                String returnLine = reader.readLine();
                System.out.println(returnLine);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                }
            }
            if (writer != null) {
                writer.close();
            }

            if (this.socket != null) {
                try {
                    this.socket.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public static void main(String[] args) {

        Configuration conf = Configuration.getInstance();

        try {
            conf.init();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        String clientKeyStore
                = conf.getProperty("net.ssl.bidirectional.client.keystore");
        String clientKeyStorePwd
                = conf.getProperty("net.ssl.bidirectional.client.keystore.pwd");
        String clientKeyStoreTrust
                = conf.getProperty("net.ssl.bidirectional.client.keystore.trust");
        String clientKeyStoreTrustPwd
                = conf.getProperty("net.ssl.bidirectional.client.keystore.trust.pwd");

        SSLTcpClient tcpClient = new SSLTcpClient();
        try {
            tcpClient.start(9000,
                    clientKeyStore,
                    clientKeyStorePwd,
                    clientKeyStoreTrust,
                    clientKeyStoreTrustPwd);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
